{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 推荐系统组队学习  概述"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 推荐系统是什么\n",
    "\n",
    "|用户|公司|\n",
    "|--|--|\n",
    "|帮助用户快速发现有用信息|增加公司产品与用户接触,购买等行为概率的工具|\n",
    "在用户需求并不十分明确的情况下进行信息的过滤,与搜索系统相比,推荐系统更多的利用用户的各类历史信息猜测其可能喜欢的内容|解决产品能够最大限度地吸引用户,留存用户,增长用户黏性,提高用户转化率,从而达到公司商目标连续增长的目的\n",
    "\n",
    "目标：解决产品能够最大限度地吸引用户,留存用户,增长用户黏性,提高用户转化率,从而达到公司商目标连续增长的目的."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 评价指标\n",
    "\n",
    "### 1.用户满意度\n",
    "\n",
    "不容易量化和离线计算的指标，通过购买率度量用户的满意度,与购买率类似的点击率, 用户停留时间和转化率等指标都可以用来度量用户的满意度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.预测准确率\n",
    "\n",
    "#### 评分预测：评分预测模型通过对用户的历史物品评分记录进行建模,进而得到用户 的兴趣模型,然后使用该模型预测用户未未见过商品的评分.\n",
    "\n",
    "对于测试集中的一个用户 和物品 ,令$r_{ui}$是用户u对物品i的实际评分,而$\\hat{r_{ui}}$是推荐模型预测出的评分\n",
    "\n",
    "两种评价实际评分与预测评分的方式：\n",
    "\n",
    "均方根误差(RMSE)：\n",
    "\n",
    "$$RMSE = \\sqrt{\\frac{\\sum_{u,i \\in T}(r_{ui} - \\hat{r}_{ui})^2}{|T|}} $$\n",
    "\n",
    "平均绝对误差(MAE)\n",
    "\n",
    "$$MAE = \\frac{\\sum_{u,i \\in T}|r_{ui} - \\hat{r}_{ui}|}{|T|} $$\n",
    "\n",
    "#### topN推荐\n",
    "\n",
    "推荐系统在给用户推荐物品的时候,往往会给用户一个列表的推荐物品,这种场景下的推荐成为是TopN推荐,该推荐方式最常用的预测准确率指标一般是精确率(precision)和召回率(recall)\n",
    "\n",
    "精确率(precision): 分类正确的正样本个数占分类器判定为正样本的样本个数比例\n",
    "\n",
    "$$ Precision= \\frac{\\sum_{u \\in U}|R(u) \\cap T(u)|}{\\sum_{u \\in U}|R(u)|}$$\n",
    "\n",
    "召回率(recall): 分类正确的正样本个数占真正的正样本个数的比例\n",
    "\n",
    "$$ Recall= \\frac{\\sum_{u \\in U}|R(u) \\cap T(u)|}{\\sum_{u \\in U}|T(u)|}$$\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3.覆盖率\n",
    "\n",
    "覆盖率是用来描述一个推荐系统对物品长尾的发掘能力,一个简单的定义可以是:推荐系统所有推荐出来的商品集合数占总物品集合数的比例\n",
    "\n",
    "但是对于相同的覆盖率,不同物品的数量分布,或者说是物品的流行度分布是可以不一样的.为了更好的描述推荐系统挖掘长尾的能力,需要统计不同物品出现次数的分布.如果所有的物品都出现在推荐列表中,并且出现的次数都差不多,那么推荐系统发掘长尾的能力就很好\n",
    "\n",
    "可以通过研究物品在推荐列表中出现的次数分布来描述推荐系统挖掘长尾的能力,如果这个分布比较平缓说明推荐系统的覆盖率比较高,而如果分布比较陡说明推荐系统的覆盖率比较低.下面分别使用信息熵和基尼系数来定义覆盖率\n",
    "\n",
    "信息熵定义覆盖率：$p(i)$是物品$i$的流行度除以所有物品流行度之和:\n",
    " \n",
    "$$ H = -\\sum_{i=1}^n p(i) logp(i)$$\n",
    " \n",
    "基尼系数定义覆盖率: 其中$i_j$是按照物品流行度$p$从小到大排序的物品列表中第j个物品:\n",
    "\n",
    "$$ G=\\frac{1}{n-1} \\sum_{j=1}^{n}(2j-n-1)p(i_{j})$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.多样性\n",
    "\n",
    "一个好的推荐系统得到的推荐列表中应该尽可能多的包含用户的兴趣,只有这样才能增加用户找到感兴趣物品的概率.度量推荐列表中物品的多样性换句话说就是度量推荐列表中所有物品之间的不相似性,可以通过不同的相似性函数来度量推荐列表中商品的相似性,比如商品基于内容的相似,基于协同过滤的相似,这样就可以得到不同角度的多样性\n",
    "\n",
    "\n",
    "s(i,j)为物品i和物品j的相似性,那么用户推荐列表的多样性可以定义为:\n",
    "\n",
    "$$Diversity(R(u))=1-\\frac{\\sum_{i,j \\in R(u)}s(i,j)}{\\frac{1}{2}|R(u)|(|R(u)|-1)}$$\n",
    "\n",
    "推荐系统整体的多样性可以定义为所有用户推荐列表多样性的平均值:\n",
    "\n",
    "$$Diversity = \\frac{1}{U} \\sum_{u\\in U}Diversity(R(u))$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5.新颖性\n",
    "\n",
    "一般会计算推荐物品的平均流行度,流行度越低的物品越有可能让用户觉得新颖,因此,如果推荐结果中的物品平均热门程度比较低说明推荐的结果就可能比较新颖"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6.AUC曲线\n",
    "\n",
    "ROC曲线下与坐标轴围成的面积\n",
    "\n",
    "ROC曲线的横坐标为假阳性率（False Positive Rate, FPR），N是真实负样本的个数， FP是N个负样本中被分类器预测为正样本的个数。\n",
    "\n",
    "AUC越接近1.0，检测方法真实性越高;等于0.5时，则真实性最低，无应用价值。\n",
    "\n",
    "AUC可以由roc_auc_score得到\n",
    "```\n",
    "rom sklearn.metrics import roc_auc_score\n",
    "y_true = np.array([0, 0, 1, 1])\n",
    "y_scores = np.array([0.1, 0.4, 0.35, 0.8])\n",
    "print('AUC socre:',roc_auc_score(y_true, y_scores))\n",
    "```\n",
    "\n",
    "**关于AUC的另外一种定义**\n",
    "\n",
    "分别随机从正负样本集合中抽取一个正样本，一个负样本，正样本的预测值大于副样本的概率\n",
    "\n",
    "$$AUC = \\frac{\\sum I(P_{positive},{P_{nagetive}})}{M*N} $$\n",
    "\n",
    "纵坐标为真阳性率（True Positive Rate, TPR），P是真实正样本的个数，TP是P个正样本中被分类器预测为正样本的个数。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 召回\n",
    "\n",
    "召回阶段负责将海量的候选集快速缩小为几万到几千的规模；而排序层则负责对缩小后的候选集进行精准排序。所以在召回阶段往往会利用少量的特征和简单的模型对大规模的数据集进行快速的筛选，而在排序层一般会使用更多的特征和更加复杂的模型进行精准的排序。\n",
    "\n",
    "|召回层|排序层|\n",
    "|--|--|\n",
    "待计算的候选集合大、计算速度快、模型简单、特征较少，尽量让用户感兴趣的物品在这个阶段能够被快速召回，即保证相关物品的召回率|首要目标是得到精准的排序结果。需要处理的物品数量少，可以利用较多的特征，使用比较复杂的模型。\n",
    "\n",
    "### 多路召回策略\n",
    "\n",
    "采用不同的策略、特征或简单模型，分别召回一部分候选集，然后把候选集混合在一起供后续排序模型使用，可以明显的看出，“多路召回策略”是在“计算速度”和“召回率”之间进行权衡的结果。其中，各种简单策略保证候选集的快速召回，从不同角度设计的策略保证召回率接近理想的状态，不至于损伤排序效果。\n",
    "\n",
    "缺点：对于每一路召回都会从商品集合中拉回K个商品，这里的K是一个超参数，对于K的选择一般需要通过离线评估加线上的A/B测试来确定合理的K值。除此之外，对于不同的任务具体策略的选择也是人工基于经验的选择，选择的策略之间的信息是割裂的，无法总和考虑不同策略对一个物品的影响。\n",
    "\n",
    "### Embedding召回\n",
    "\n",
    "主要目的是将稀疏的向量(如one-hot编码)表示转换成稠密的向量，即Embedding相当于是对one-hot做了平滑，而onehot相当于是对Embedding做了max pooling。\n",
    "\n",
    "分类  \n",
    "text embedding  \n",
    "image embedding  \n",
    "graph embedding  \n",
    "\n",
    "常见的text Embedding的技术有：\n",
    "\n",
    "静态向量：word2vec, fasttext, glove  \n",
    "动态向量：ELMO, GPT, BERT  \n",
    "\n",
    "动态词向量相较于静态词向量，更加充分利用了上下文信息，所以可以解决一词多义的问题。在工程实践上其优越性也得到了证明（BERT 在多个 NLP 任务中也表现优异）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如何使用推荐系统 embedding\n",
    "\n",
    "参考自：https://zhuanlan.zhihu.com/p/143763320\n",
    "\n",
    "embedding 其实就是一种稠密向量的表示形式，直观上看 embedding 相当于是对 oneHot 做了平滑，而 oneHot 相当于是对 embedding 做了max pooling"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
